/*
 * File:   ClientProtocol.h
 * Author: wilq
 *
 * Created on June 10, 2012, 12:30 PM
 */

#ifndef CLIENTPROTOCOL_H
#define	CLIENTPROTOCOL_H
#include <string>
#include "NetworkProtocol.h"
#include "NetworkPacket.h"
#include "Packets.h"
#include "File.h"
#include "Folder.h"
#include "User.h"
#include "Storage.h"
#include "Group.h"

typedef uint32_t THANDLE;

using namespace std;
using namespace CSNetworkLib;
using namespace CSApi;

class ClientProtocol : public CSNetworkLib::NetworkProtocol {
public:
    ClientProtocol(socket_ptr s);
    virtual ~ClientProtocol();

    /**
     * Autoryzacja użytkownika
     * @param name nazwa użytkownika
     * @param password hasło użytkownika
     * @return status operacji
     */
    int32_t UserAuthorization(const string &name, const string &password);
    
    /**
     * Pobiera listę plików w katalogu
     * @param folderId identyfikator pliku
     * @return lista plików
     */
    vector<File> GetFilesInDir(uint32_t folderId);
    
    /**
     * Pobiera listę plików w katalogu
     * @param folderId identyfikator katalogu
     * @return lista folderów
     */
    vector<Folder> GetFoldersInDir(uint32_t folderId);

    /**
     * Otwiera plik
     * @param fileId - identyfikator pliku
     * @param parentFolderId identyfikator katalogu nadrzędnego
     * @param name nazwa pliku
     * @param type atrybuty otwarcia 
     * @return status operacji
     */
    int32_t OpenFile(uint32_t fileId, uint32_t parentFolderId, string name, string type);
    
    /**
     * Zamyka plik
     * @param fileId identyfikator pliku
     * @return status operacji
     */
    int32_t CloseFile(uint32_t fileId);
    
    /**
     * Zmienia nazwę pliku
     * @param fileId identyfikator pliku
     * @param name nazwa pliku
     * @return status operacji
     */
    int32_t RenameFile(uint32_t fileId, string name);

    /**
     * Tworzy katalog
     * @param folderId identyfikator katalogu
     * @param name nazwa 
     * @return status operacji
     */
    int32_t MakeDirectory(uint32_t folderId, string name);
    
    /**
     * Usuwa katalog
     * @param folderId identyfikator katalogu
     * @return status operacji
     */
    int32_t DeleteDirectory(uint32_t folderId);
    
    /**
     * Zmienia nazwę katalogu
     * @param folderId identyfikator katalogu
     * @param name nazwa katalogu
     * @return status operacji
     */
    int32_t RenameDirectory(uint32_t folderId, string name);

    /**
     * Dodaję użytkownika
     * @param name nazwa użtykownika
     * @param password hasło użytkownika 
     * @return status operacji
     */
    int32_t AddUser(string name, string password);
    
    /**
     * Zmienia nazwę użytkownika
     * @param name nazwa użytkownika
     * @param password hasło użytkownika
     * @return status operacji
     */
    int32_t ChangeUserPassword(string name, string password);
    
    /**
     * Usuwa użytkownka 
     * @param userId identyfikator użytkownika
     * @return status operacji
     */
    int32_t RemoveUser(uint32_t userId);
    
    /**
     * Pobiera listę użytkowników
     * @return lista użytkowników
     */
    vector<User> GetUsersList();

    /**
     * Dodaję grupę 
     * @param name nazwa grupy
     * @return status operacji
     */
    int32_t AddGroup(string name);
    
    /**
     * Usuwa grupę użytkowników
     * @param groupId identyfikator grupy
     * @return status operacji
     */
    int32_t RemoveGroup(uint32_t groupId);
    
    /**
     * pobiera listę grup
     * @return lista grup
     */
    vector<Group> GetGroupList();

    /**
     * Dodaję magazyn
     * @param name nazwa magazynu
     * @param key klucz magazynu
     * @return 
     */
    int32_t AddStorage(string name, string key);
    
    /**
     * Usuwa magazyn
     * @param storageId identyfikator magazynu
     * @return status operacji
     */
    int32_t RemoveStorage(uint32_t storageId);
    
    /**
     * Zmienia klucz magazynu
     * @param storage identyfikoatr magazynu
     * @param key nowy klucz magazynu
     * @return status operacji
     */
    int32_t ChangeStorageKey(string storage, string key);
    
    /**
     * Pobiera listę magazynów
     * @return lista magazynów
     */
    vector<Storage> GetStorageList();

    /**
     * Udostępnia katalog
     * @param virtualPath scieżka wirutalna
     * @param storagePath scieżka w magazynie
     * @param storageName naza magazynu
     * @param force wymuszenie
     * @return status operacji
     */
    bool Share(const std::string &virtualPath, const std::string &storagePath, const std::string &storageName, bool force);
    
    /**
     * Zatrzymuję udostępnianie katalogu
     * @param virtualPath wirtualna ścieżka 
     * @param remove wymuszenie usunięcia
     * @return 
     */
    bool UnShare(const std::string &virtualPath, bool remove);

    /**
     * Sprawdza czy plik istnieje
     * @param path scieżka do pliku
     * @return status operacji
     */
    bool FileExists(const std::string &path);
    
    /**
     * Otwiera plik
     * @param path scieżka do pliku
     * @param mode atrybut otwrcia pliku jak w fopen
     * @return uchwyt do pliku
     */
    THANDLE FileOpen(const std::string &path, const std::string &mode);
    
    /**
     * Zamyka plik
     * @param handle uchwyt do pliku
     * @return status operacji
     */
    bool FileClose(THANDLE handle);
    
    /**
     * Sprawdza czy kursor jest na końcu pliku
     * @param handle uchwyt do pliku
     * @return status operacji
     */
    bool FileEof(THANDLE handle);
    
    /**
     * Pobiera informację na temat pliku
     * @param handle uchwyt do pliku
     * @param mode atrybut otwarcia
     * @return 
     */
    uint64_t FileInfo(THANDLE handle, uint8_t mode);
    
    /**
     * zmienia pozycję kursora w pliku
     * @param handle
     * @param position
     * @return 
     */
    bool FileSeek(THANDLE handle, int64_t position /*-1 for end*/);
    
    /**
     * Zapisuję dane do pliku
     * @param handle uchwyt 
     * @param size romizar buffora danych
     * @param data buffor danych
     * @return ilość zapisanych bajtów
     */
    uint32_t FileWrite(THANDLE handle, uint32_t size, const uint8_t *data);
    
    /**
     * Odczytuję dane z pliku
     * @param handle uchwyt do pliku
     * @param size rozmiar odczytywanych danych
     * @param data buffor
     * @return ilość odczytanych danych
     */
    uint32_t FileRead(THANDLE handle, uint32_t size, uint8_t *data);
    
    /**
     * Usuwa plik
     * @param path scieżka do pliku
     * @return status operacji
     */
    bool FileDelete(const std::string &path);

private:
    /**
     * Pobiera string z pakietu
     * @param packet pakiet z którego będzie odczytywane
     * @param position pozycja
     * @return odczytany string
     */
    string _Get_String(const NetworkPacket &packet, uint32_t position);
    
    /**
     * Pobiera zapisany plik w pakiecie
     * @param packet pakiet 
     * @param position pozycja z której będzie odczytywane
     * @return plik odczytany z pakietu
     */
    File _Get_File(NetworkPacket &packet, uint32_t &position);
    
    /**
     * Pobiera folder z pakietu
     * @param packet pakiet
     * @param position pozycja
     * @return odczytany folder
     */
    Folder _Get_Folder(NetworkPacket &packet, uint32_t &position);

    /**
     * Pobiera użytkownika
     * @param packet pakiet
     * @param position pozycja
     * @return pobrany użytkownik
     */
    User _Get_User(NetworkPacket &packet, uint32_t &position);
    
    /**
     * Pobiera grupę 
     * @param packet pakiet 
     * @param position pozycja
     * @return pobrana grupę
     */
    Group _Get_Group(NetworkPacket &packet, uint32_t &position);
    
    /**
     * Pobiera magazyn
     * @param packet pakiet
     * @param position pozycja
     * @return pobrany magazyn
     */
    Storage _Get_Storage(NetworkPacket &packet, uint32_t &position);
};

#endif	/* CLIENTPROTOCOL_H */